package net.xdclass.service.impl;

import com.alibaba.fastjson.JSON;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import net.xdclass.constant.CacheKey;
import net.xdclass.enums.BizCodeEnum;
import net.xdclass.exception.BizException;
import net.xdclass.intercepto.LoginInterceptor;
import net.xdclass.model.LoginUser;
import net.xdclass.request.CartItemRequest;
import net.xdclass.service.CartService;
import net.xdclass.service.ProductService;
import net.xdclass.vo.CartItemVO;
import net.xdclass.vo.CartVO;
import net.xdclass.vo.ProductVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CartServiceImpl implements CartService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ProductService productService;

    @Override
    public void addToCart(CartItemRequest cartItemRequest) {
        long productId = cartItemRequest.getProductId();
        int buyNum = cartItemRequest.getBuyNum();
        //获取购物车
        BoundHashOperations<String, Object, Object> myCartOps = getMyCartOps();
        Object cartObj = myCartOps.get(productId);
        String result = "";
        if (cartObj != null) {
            result = (String) cartObj;
        }
        if (StringUtils.isBlank(result)) {
            //商品不存在 新增
            ProductVO detailById = productService.findDetailById(productId);
            if (detailById == null) {
                throw new BizException(BizCodeEnum.ORDER_CONFIRM_CART_ITEM_NOT_EXIST);
            }
            CartItemVO cartItemVO = new CartItemVO();
            cartItemVO.setAmount(detailById.getAmount());
            cartItemVO.setBuyNum(buyNum);
            cartItemVO.setProductId(productId);
            myCartOps.put(productId, JSON.toJSONString(cartItemVO));
        } else {
            //存在则修改数量
            CartItemVO cartItemVO = JSON.parseObject(result, CartItemVO.class);
            cartItemVO.setBuyNum(cartItemVO.getBuyNum() + buyNum);
            myCartOps.put(productId, JSON.toJSONString(cartItemVO));
        }
    }

    @Override
    public void changeItemNum(CartItemRequest cartItemRequest) {
        BoundHashOperations<String,Object,Object> mycart =  getMyCartOps();
        Object cacheObj = mycart.get(cartItemRequest.getProductId());
        if(cacheObj==null){throw new BizException(BizCodeEnum.ORDER_CONFIRM_CART_ITEM_NOT_EXIST);}

        String obj = (String)cacheObj;

        CartItemVO cartItemVO =  JSON.parseObject(obj,CartItemVO.class);
        cartItemVO.setBuyNum(cartItemRequest.getBuyNum());
        mycart.put(cartItemRequest.getProductId(),JSON.toJSONString(cartItemVO));
    }

    @Override
    public void clear() {
        String cartKey = getCartKey();
        redisTemplate.delete(cartKey);
    }

    @Override
    public CartVO getMyCart() {
        List<CartItemVO> cartItemVOList = buildCartItem(false);
        CartVO cartVO =new CartVO();
        cartVO.setCartItems(cartItemVOList);
        return cartVO;
    }

    /**
     * 获取最新购物车
     *是否获取最新价格
     * @param leatestPrice
     * @return
     */
    private List<CartItemVO> buildCartItem(boolean leatestPrice) {
        BoundHashOperations<String, Object, Object> myCartOps = getMyCartOps();
        List<Object> itemList = myCartOps.values();
        List<CartItemVO> cartItemVOList = new ArrayList<>();
        List<Long> productIdList = new ArrayList<>();
        for (Object item : itemList) {
            CartItemVO cartItemVO = JSON.parseObject((String) item, CartItemVO.class);
            cartItemVOList.add(cartItemVO);
            productIdList.add(cartItemVO.getProductId());
        }
        //查询最新的商品价格
        if (leatestPrice){
            setProductLeast(cartItemVOList,productIdList);
        }

        return cartItemVOList;
    }

    /**
     * 设置商品最新价格
     * @param cartItemVOList
     * @param productIdList
     */
    private void setProductLeast(List<CartItemVO> cartItemVOList, List<Long> productIdList) {
        List<ProductVO> productByIdBatch = productService.findProductByIdBatch(productIdList);
        Map<Long, ProductVO> productVOMap = productByIdBatch.stream().collect(Collectors.toMap(ProductVO::getId, Function.identity()));
        cartItemVOList.stream().forEach(item->{
            ProductVO productVO = productVOMap.get(item.getProductId());
            item.setProductTitle(productVO.getTitle());
            item.setProductImg(productVO.getCoverImg());
            item.setAmount(productVO.getAmount());
        });

    }

    @Override
    public void deleteItem(long productId) {

        BoundHashOperations<String,Object,Object> mycart =  getMyCartOps();

        mycart.delete(productId);
    }

    /**
     * 抽取我的购物车 公用方法
     *
     * @return
     */
    private BoundHashOperations<String, Object, Object> getMyCartOps() {
        String cartKey = getCartKey();
        return redisTemplate.boundHashOps(cartKey);
    }

    /**
     * 购物车key
     *
     * @param productIdList
     * @return 购物车数据结构 Map<String,Map<String,Object>> 第一个key是用户的id 第二个key是物品的id
     */
    @Override
    public List<CartItemVO> confirmOrderCartItems(List<Long> productIdList) {
        return null;
    }

    private String getCartKey() {
        LoginUser loginUser = LoginInterceptor.threadLocal.get();
        String cacheKey = String.format(CacheKey.CART_KEY, loginUser.getId());

        return cacheKey;
    }
}
